import java_cup.runtime.Symbol;
import java.io.FileInputStream;
import java.io.InputStream;



%%
%cup
%line

%{
	public Symbol token(int tokenId) {
		return new Symbol(tokenId, yyline, yycolumn);
	}

	public Symbol token(int tokenId, Object value) {
		return new Symbol(tokenId, yyline, yycolumn, value);
	}

	public static void main(String args[]) throws Exception {
		InputStream is = new FileInputStream(args[0]);
		Yylex lexer = new Yylex(is);

		Symbol token = null;
		do {
			token = lexer.next_token();
			System.out.println(token == null ? "EOF" : token.toString());
			if(token.toString().equals("#0")) {
				break;
			}		
		} while (token != null);
	}
	
	private int countLines(String str){
		int count = 0;
		for(int i = 0; i < str.length(); ++i){
			if(str.charAt(i) == '\n'){
				++count;
			}
		}
		return count;
	}
%}

/* pattern definition */
LineTerminator     = \r|\n| \r\n
InputCharacter     = [^\r\n]

WHITESPACE         = {LineTerminator} | [ \t\f]

TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/"
EndOfLineComment   = "//" {InputCharacter}* {LineTerminator}

COMMENT            = {TraditionalComment} | {EndOfLineComment}

ID                 = [a-zA-Z][a-zA-Z0-9]*
INTEGER_LITERAL    = 0 | [1-9][0-9]*
DOUBLE_LITERAL     = [0-9]+ ("."[0-9]+)?
STRING_LITERAL     = "\""([^\n\"\\]*(\\[.\n])*)*"\""

%%

/* keywords */
"add"              { return token(sym.ADD);}
"arraylist"        { return token(sym.ARRAYLIST);}
"break"            { return token(sym.BREAK);}
"continue"         { return token(sym.CONTINUE);}
"def"              { return token(sym.DEF);}
"def_btn"          { return token(sym.DEF_BTN);}
"def_timer"        { return token(sym.DEF_TIMER);}
"do"               { return token(sym.DO);}
"double"           { return token(sym.DOUBLE);}
"else"             { return token(sym.ELSE);}
"extends"          { return token(sym.EXTENDS);}
"false"            { return token(sym.FALSE);}
"final"            { return token(sym.FINAL);}
"for"              { return token(sym.FOR);}
"if"               { return token(sym.IF);}
"Image"            { return token(sym.IMAGE);}
"int"              { return token(sym.INTEGER);}
"Item"             { return token(sym.ITEM);}
"Panel"            { return token(sym.PANEL);}
"Pet"              { return token(sym.PET);}
"Program"	   { return token(sym.PROGRAM);}
"print"            { return token(sym.PRINT);}
"remove"           { return token(sym.REMOVE);}
"removeAll"        { return token(sym.REMOVEALL);}
"return"           { return token(sym.RETURN);}
"size"		   { return token(sym.SIZE);}
"Sound"            { return token(sym.SOUND);}
"string"           { return token(sym.STRING);}
"true"             { return token(sym.TRUE);}
"void"             { return token(sym.VOID);}
"while"            { return token(sym.WHILE);}

/* string */
{STRING_LITERAL}   { return token(sym.STRING_LITERAL, yytext());}
/* comment */
{COMMENT}          {/* Ignored*/}

/* white space */
{WHITESPACE}       {/* Ignored*/}
 
/* operators */
"+"                { return token(sym.PLUS);}
"-"                { return token(sym.MINUS);}
"*"                { return token(sym.TIMES);}
"/"                { return token(sym.DIVIDE);}
"="                { return token(sym.ASSIGN);}
"<"                { return token(sym.LESS);}
"<="               { return token(sym.LESS_EQUAL);}
">="               { return token(sym.GREATER_EQUAL);}
">"                { return token(sym.GREATER);}
"=="               { return token(sym.EQUAL);}
"!="               { return token(sym.NOT_EQUAL);}
"{"                { return token(sym.LEFT_BRACE);}
"}"                { return token(sym.RIGHT_BRACE);}
"["                { return token(sym.LEFT_BRACKET);}
"]"                { return token(sym.RIGHT_BRACKET);}
"("                { return token(sym.LEFT_PARENTHESE);}
")"                { return token(sym.RIGHT_PARENTHESE);}
"||"               { return token(sym.OR);}
"&&"               { return token(sym.AND);}
";"                { return token(sym.SEMI);}
","                { return token(sym.COMMA);}
"\""               { return token(sym.QUOTE); }

/* separator */
"."                { return token(sym.DOT);}

/* identifier */
{ID}               { return token(sym.ID, yytext()); }

/* number */
{INTEGER_LITERAL}  { return token(sym.INTEGER_LITERAL, new Integer(yytext()));}
{DOUBLE_LITERAL}   { return token(sym.DOUBLE_LITERAL, new Double(yytext()));}

[\n]			   { ++yyline;}
[\r\t\f\ ]+	       {  }
